package com.hxrfid.project.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.hxrfid.common.constant.BasicConstants;
import com.hxrfid.common.core.domain.PageQuery;
import com.hxrfid.common.core.domain.entity.SysUser;
import com.hxrfid.common.core.domain.model.LoginUser;
import com.hxrfid.common.core.page.TableDataInfo;
import com.hxrfid.common.exception.ServiceException;
import com.hxrfid.common.helper.LoginHelper;
import com.hxrfid.common.utils.ImageUtils;
import com.hxrfid.project.domain.BsCardList;
import com.hxrfid.project.domain.BsMoneyRecord;
import com.hxrfid.project.domain.bo.BsCardListBo;
import com.hxrfid.project.domain.vo.BsCardListVo;
import com.hxrfid.project.domain.vo.BsCardVo;
import com.hxrfid.project.mapper.BsCardListMapper;
import com.hxrfid.project.mapper.BsCardMapper;
import com.hxrfid.project.mapper.BsMoneyRecordMapper;
import com.hxrfid.project.service.IBsCardListService;
import com.hxrfid.system.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 实体卡列Service业务层处理
 *
 * @author hxrfid
 * @date 2025-07-04
 */
@RequiredArgsConstructor
@Service
public class BsCardListServiceImpl extends ServiceImpl<BsCardListMapper, BsCardList> implements IBsCardListService {

    private final BsCardListMapper baseMapper;
    private final BsCardMapper bsCardMapper;
    private final SysUserMapper sysUserMapper;
    private final BsMoneyRecordMapper bsMoneyRecordMapper;

    /**
     * 查询实体卡列
     * @param id 主键ID
     * @return 实体卡列
     */
    @Override
    public BsCardListVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询实体卡列列表
     * @param bo 实体卡列对象
     * @param pageQuery 主键ID
     * @return 实体卡列列表
     */
    @Override
    public TableDataInfo<BsCardListVo> queryPageList(BsCardListBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<BsCardList> lqw = buildQueryWrapper(bo);
        Page<BsCardListVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        List<BsCardListVo> records = result.getRecords();
        BigDecimal cardPrice = BigDecimal.ZERO;
        if (CollectionUtil.isNotEmpty(records)) {
            BsCardVo bsCardVo = bsCardMapper.selectVoById(records.get(0).getCardId());
            cardPrice = bsCardVo.getCardPrice();
        }
        for (BsCardListVo item : records) {
            item.setCardPrice(cardPrice);
            // 转Base64
            String base64 = ImageUtils.bufferedImageToBase64(item.getId().toString());
            item.setQrCode(base64);
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询实体卡列列表
     * @param bo 实体卡列对象
     * @return 实体卡列列表
     */
    @Override
    public List<BsCardListVo> queryList(BsCardListBo bo) {
        LambdaQueryWrapper<BsCardList> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
    * 组装查询条件
    * @param bo 实体卡列对象
    * @return 查询条件
    */
    private LambdaQueryWrapper<BsCardList> buildQueryWrapper(BsCardListBo bo) {
        if (!LoginHelper.isAdmin() && !LoginHelper.isTenantAdmin()) {
            bo.setUserId(LoginHelper.getUserId());
        }
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<BsCardList> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getCardId() != null, BsCardList::getCardId, bo.getCardId());
        lqw.eq(bo.getUserId() != null, BsCardList::getUserId, bo.getUserId());
        lqw.eq(bo.getTenantId() != null, BsCardList::getTenantId, bo.getTenantId());
        return lqw;
    }

    /**
     * 新增实体卡列
     * @param bo 实体卡列对象
     * @return 是否成功
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean insertByBo(BsCardListBo bo) {
        List<BsCardList> addList = Lists.newArrayList();
        Integer cardNum = bo.getCardNum();
        for (int i = 0; i < cardNum; i++) {
            BsCardList add = BeanUtil.toBean(bo, BsCardList.class);
            validEntityBeforeSave(add);
            addList.add(add);
        }
        return baseMapper.insertBatch(addList);
    }

    /**
     * 修改实体卡列
     * @param bo 实体卡列对象
     * @return 是否成功
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean updateByBo(BsCardListBo bo) {
        BsCardList update = BeanUtil.toBean(bo, BsCardList.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     * @param entity 实体卡列对象
     */
    private void validEntityBeforeSave(BsCardList entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除实体卡列
     * @param ids 主键ID的list
     * @param isValid 是否业务校验
     * @return 是否成功
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 修改实体卡列
     * @param bo 实体卡列对象
     * @return 激活后的订单信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean activeCard(BsCardListBo bo) {
        // 查询卡是否已被激活
        Long id = bo.getId();
        BsCardListVo bsCardListVo = baseMapper.selectVoById(id);
        Assert.isFalse(ObjectUtil.isNull(bsCardListVo), "未查询到该卡片！");
        Assert.isFalse(BasicConstants.STR_TWO.equals(bsCardListVo.getActive()), "该卡片已被激活！");
        LoginUser loginUser = LoginHelper.getLoginUser();
        BsCardList bean = BeanUtil.toBean(bo, BsCardList.class);
        bean.setUserId(loginUser.getUserId());
        bean.setNickName(loginUser.getNickName());
        bean.setActive(BasicConstants.STR_TWO);
        // 激活卡片
        int update = baseMapper.updateById(bean);
        if (update > 0) {
            addMoneyRecord(loginUser.getUserId(), bo.getId());
            return true;
        } else {
            throw new ServiceException("激活会员卡失败");
        }
    }

    /**
     * 添加用户余额和积分变动记录
     * @param userId 用户ID
     * @param id 实体卡ID
     */
    private void addMoneyRecord(Long userId, Long id) {
        // 查询用户
        SysUser sysUser = sysUserMapper.selectVoOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUserId, userId));
        // 查询卡片价格
        BsCardListVo bsCardListVo = baseMapper.selectVoById(id);
        BsCardVo bsCardVo = bsCardMapper.selectVoById(bsCardListVo.getCardId());
        sysUser.setMoney(sysUser.getMoney().add(bsCardVo.getCardPrice()));
        // 更新用户余额
        sysUserMapper.updateById(sysUser);
        // 添加用户余额和积分变动记录
        BsMoneyRecord bsMoneyRecord = new BsMoneyRecord();
        bsMoneyRecord.setTitle(String.format("激活卡片【%s】", id));
        bsMoneyRecord.setChangeNum("+" + bsCardVo.getCardPrice());
        bsMoneyRecord.setChangeType(BasicConstants.STR_ONE);
        bsMoneyRecord.setUserId(userId);
        bsMoneyRecord.setRealPrice(bsCardVo.getCardPrice());
        bsMoneyRecordMapper.insert(bsMoneyRecord);
    }
}
